//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.Text;
using System.Configuration.Provider;
using System.Configuration;
using System.Web.Hosting;
using System.Web.Configuration;
using System.Collections.Specialized;

namespace NopSolutions.NopCommerce.DataAccess.Audit
{
    /// <summary>
    /// Acts as a base class for deriving custom search log provider
    /// </summary>
    public abstract class DBSearchLogProvider : ProviderBase
    {
        #region Fields
        private static bool s_Initialized;
        private static Exception s_InitializeException;
        private static object s_lock;
        private static DBSearchLogProvider s_Provider;
        private static DBSearchLogProviderCollection s_Providers;
        #endregion

        #region Ctor
        /// <summary>
        /// Initializes a new instance of the DBSearchLogProvider class.
        /// </summary>
        static DBSearchLogProvider()
        {
            s_lock = new object();
            s_Initialized = false;
            s_InitializeException = null;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Get order product variant sales report
        /// </summary>
        /// <param name="StartTime">Order start time; null to load all</param>
        /// <param name="EndTime">Order end time; null to load all</param>
        /// <param name="Count">Item count. 0 if you want to get all items</param>
        /// <returns>Result</returns>
        public abstract IDataReader SearchTermReport(DateTime? StartTime, DateTime? EndTime, int Count);
       
        /// <summary>
        /// Gets all search log items
        /// </summary>
        /// <returns>Search log collection</returns>
        public abstract DBSearchLogCollection GetAllSearchLogs();

        /// <summary>
        /// Gets a search log item
        /// </summary>
        /// <param name="SearchLogID">The search log item identifier</param>
        /// <returns>Search log item</returns>
        public abstract DBSearchLog GetSearchLogByID(int SearchLogID);

        /// <summary>
        /// Inserts a search log item
        /// </summary>
        /// <param name="SearchTerm">The search term</param>
        /// <param name="CustomerID">The customer identifier</param>
        /// <param name="CreatedOn">The date and time of instance creation</param>
        /// <returns>Search log item</returns>
        public abstract DBSearchLog InsertSearchLog(string SearchTerm, int CustomerID, DateTime CreatedOn);

        #endregion

        #region Utilities
        /// <summary>
        /// Returns the configuration section.
        /// </summary>
        /// <returns>The ConfigurationSection object.</returns>
        private static DBSearchLogProviderSection GetSection()
        {
            return (DBSearchLogProviderSection)ConfigurationManager.GetSection("nopDataProviders/SearchLogProvider");
        }
        private static void Initialize()
        {
            if (s_Initialized)
            {
                if (s_InitializeException != null)
                {
                    throw s_InitializeException;
                }
            }
            else
            {
                if (s_InitializeException != null)
                {
                    throw s_InitializeException;
                }
                lock (s_lock)
                {
                    if (s_Initialized)
                    {
                        if (s_InitializeException != null)
                        {
                            throw s_InitializeException;
                        }
                    }
                    else
                    {
                        try
                        {
                            DBSearchLogProviderSection section = GetSection();
                            if (((section.DefaultProvider == null) || (section.Providers == null)) || (section.Providers.Count < 1))
                            {
                                throw new ProviderException("Default provider not specified");
                            }
                            s_Providers = new DBSearchLogProviderCollection();
                            if (HostingEnvironment.IsHosted)
                            {
                                ProvidersHelper.InstantiateProviders(section.Providers, s_Providers, typeof(DBSearchLogProvider));
                            }
                            else
                            {
                                foreach (ProviderSettings settings in section.Providers)
                                {
                                    Type c = Type.GetType(settings.Type, true, true);
                                    if (!typeof(DBSearchLogProvider).IsAssignableFrom(c))
                                    {
                                        throw new ArgumentException(string.Format("Provider must implement {0} type", new object[] { typeof(DBSearchLogProvider).ToString() }));
                                    }
                                    DBSearchLogProvider provider = (DBSearchLogProvider)Activator.CreateInstance(c);
                                    NameValueCollection parameters = settings.Parameters;
                                    NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal);
                                    foreach (string str2 in parameters)
                                    {
                                        config[str2] = parameters[str2];
                                    }
                                    provider.Initialize(settings.Name, config);
                                    s_Providers.Add(provider);
                                }
                            }
                            s_Provider = s_Providers[section.DefaultProvider];
                            if (s_Provider == null)
                            {
                                throw new ConfigurationErrorsException(string.Format("Default provider not found. {0}. Line number: {1}", section.ElementInformation.Properties["defaultProvider"].Source, section.ElementInformation.Properties["defaultProvider"].LineNumber));
                            }
                            s_Providers.SetReadOnly();
                        }
                        catch (Exception exception)
                        {
                            s_InitializeException = exception;
                            throw;
                        }
                        s_Initialized = true;
                    }
                }
            }
        }

        #endregion

        #region Properties
        /// <summary>
        /// Gets a reference to the default provider for the application.
        /// </summary>
        public static DBSearchLogProvider Provider
        {
            get
            {
                Initialize();
                return s_Provider;
            }
        }
        /// <summary>
        /// Gets a collection of the providers for the application.
        /// </summary>
        public static DBSearchLogProviderCollection Providers
        {
            get
            {
                Initialize();
                return s_Providers;
            }
        }

        #endregion
    }
}
